package com.recsmile.rpc.provider;

import com.recsmile.rpc.bo.RpcThreadPool;
import com.recsmile.rpc.provider.net.RpcMessageSenderInitTask;
import com.recsmile.rpc.provider.net.codec.MessageSendHandler;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;

import java.net.InetSocketAddress;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Administrator on 2016/8/3.
 */
public class RpcServerLoader {
    private static RpcServerLoader instance;
    private MessageSendHandler messageSendHandler;
    private Lock lock = new ReentrantLock();
    private Condition finish = lock.newCondition();
    private ThreadPoolExecutor executor = RpcThreadPool.createExecutor(16, -1);
    private EventLoopGroup eventLoopGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors() * 2);

    private RpcServerLoader(){
    }

    public static RpcServerLoader instance(){
        if(instance == null){
            synchronized (RpcServerLoader.class){
                if( instance == null){
                    instance = new RpcServerLoader();
                }
            }
        }
        return instance;
    }

    public void load(String serverAddress){
        String[] infos = serverAddress.split(":");
        if(infos.length == 2){
            executor.submit( new RpcMessageSenderInitTask(new InetSocketAddress(infos[0], Integer.parseInt(infos[1])),eventLoopGroup,this));
        }
    }

    public void unload(){
        messageSendHandler.close();
        eventLoopGroup.shutdownGracefully();
        executor.shutdown();
    }

    public MessageSendHandler getMessageSendHandler() throws Exception{
        try {
            lock.lock();
            if ((messageSendHandler == null)){
                finish.await();
            }

        }finally {
            lock.unlock();

        }
        return messageSendHandler;
    }

    public void setMessageSendHandler(MessageSendHandler messageSendHandler) throws Exception{
        try {
            lock.lock();
            this.messageSendHandler = messageSendHandler;
            finish.signalAll();
        }finally {
            lock.unlock();

        }

    }
}
